import os
import re
import socket
import sys
import threading
import time

import requests
from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox, QFileDialog, QButtonGroup
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

from index import Ui_OpenSSLUtil
from utils import md5Util, opensslUtil, dateTimeUtil


class MyWindow(QMainWindow, Ui_OpenSSLUtil):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setWindowTitle("OpenSSLUtil")
        self.setupUi(self)
        self.tabWidget.currentChanged.connect(self.update_time)
        self.pushButton.clicked.connect(self.create_csr_file)
        self.pushButton_2.clicked.connect(lambda: self.show_key(1))
        self.pushButton_3.clicked.connect(lambda: self.show_key(2))
        self.pushButton_12.clicked.connect(self.md5_encode)
        self.pushButton_4.clicked.connect(self.select_file)
        self.pushButton_5.clicked.connect(self.cer_file_sign)
        self.pushButton_7.clicked.connect(self.select_cer_file)
        self.pushButton_9.clicked.connect(self.select_cer_key_file)
        self.pushButton_6.clicked.connect(self.create_p12)
        self.pushButton_13.clicked.connect(lambda: self.show_ca_key(1))
        self.pushButton_14.clicked.connect(lambda: self.show_ca_key(2))
        self.pushButton_10.clicked.connect(self.get_ip_info)
        self.button_group = QButtonGroup(self)
        self.button_group.addButton(self.radioButton)
        self.button_group.addButton(self.radioButton_2)
        self.pushButton_11.clicked.connect(self.time_transformation)

    # 在这里添加你的逻辑代码
    # 例如，连接按钮点击事件到相应的函数

    def create_csr_file(self):
        sv = opensslUtil.Sovereign
        file_name = self.lineEdit_6.text()
        sv.organization_name = self.lineEdit.text()
        sv.department_name = self.lineEdit_2.text()
        sv.city_name = self.lineEdit_3.text()
        sv.province_name = self.lineEdit_4.text()
        sv.country_name = self.lineEdit_5.text()
        sv.common_name = 'unknown'
        sv.encryption_algorithm = self.comboBox.currentText()
        sv.hash = self.comboBox_2.currentText()
        sv.bit_num = self.comboBox_3.currentText()
        if len(sv.organization_name) == 0:
            QMessageBox.critical(None, "提示", "请填写组织信息")
            return
        if len(sv.department_name) == 0:
            QMessageBox.critical(None, "提示", "请填写部门信息")
            return
        if len(sv.city_name) == 0:
            QMessageBox.critical(None, "提示", "请填写城市信息")
            return

        if len(sv.province_name) == 0:
            QMessageBox.critical(None, "提示", "请填写省份信息")
            return

        if len(sv.country_name) == 0:
            QMessageBox.critical(None, "提示", "请填写国家信息")
            return

        if len(file_name) == 0:
            QMessageBox.critical(None, "提示", "请填写证书保存地址")
            return

        opensslUtil.csr_sign(sv, file_name)
        QMessageBox.information(None, "提示", "证书和私钥已生成")

    def show_key(self, key_type: int):
        file_name = self.lineEdit_6.text()
        if len(file_name) == 0:
            QMessageBox.critical(None, "提示", "请填写证书保存地址")
            return
        if not os.path.exists(file_name + '/private.pem'):
            QMessageBox.critical(None, "提示", "未找到私钥证书")
            return

        if key_type == 1:
            self.label_11.setText("私钥内容")
            content = opensslUtil.get_ca_private_key(file_name + "/private_key.pem")
        else:
            self.label_11.setText("公钥内容")
            content = opensslUtil.get_ca_public_key(file_name + "/private_key.pem")
        self.plainTextEdit.setPlainText(content)

    def md5_encode(self):
        res = md5Util.encode(self.lineEdit_17.text())
        self.lineEdit_18.setText(res['bt32up'])
        self.lineEdit_19.setText(res['bt32sp'])
        self.lineEdit_20.setText(res['bt16up'])
        self.lineEdit_21.setText(res['bt16sp'])

    def select_file(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "选择一个文件", "", "All Files (*.csr);")
        if file_name:
            self.lineEdit_7.setText(file_name)
            self.lineEdit_8.setText(file_name[0:-16])


    def select_cer_file(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "选择一个文件", "", "All Files (*.cer);")
        if file_name:
            self.lineEdit_10.setText(file_name)

    def select_cer_key_file(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "选择一个文件", "", "All Files (*.pem);")
        if file_name:
            self.lineEdit_11.setText(file_name)

    def cer_file_sign(self):
        path = self.lineEdit_7.text()
        valid_days = self.lineEdit_22.text()
        out = self.lineEdit_8.text()
        opensslUtil.ca_sign(path, out, int(valid_days))
        QMessageBox.information(None, "提示", "CA证书和CA私钥已生成")

    def show_ca_key(self, num: int):
        file_name = self.lineEdit_8.text()
        if len(file_name) == 0:
            QMessageBox.critical(None, "提示", "请填写证书保存地址")
            return
        if not os.path.exists(file_name + '/CA_private.pem'):
            QMessageBox.critical(None, "提示", "未找到私钥证书")
            return
        if num == 1:
            self.label_39.setText("私钥内容")
            content = opensslUtil.get_ca_private_key(file_name + "/CA_private.pem")
        else:
            self.label_39.setText("公钥内容")
            content = opensslUtil.get_ca_public_key(file_name + "/CA_private.pem")
        self.plainTextEdit_2.setPlainText(content)

    def create_p12(self):
        cer = self.lineEdit_10.text()
        key = self.lineEdit_11.text()
        password = self.lineEdit_15.text()
        out = self.lineEdit_9.text()
        opensslUtil.p12_factory(cer, key, password, out)
        QMessageBox.information(None, "提示", "P12证书已生成")

    def get_ip_info(self):
        content = self.lineEdit_12.text()
        if content == '':
            QMessageBox.critical(None, "提示", "请填写地址或域名")
            return
        if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", content) is None:
            if re.match(r"^.*?\.*.+?\.\w+$", content) is None:
                QMessageBox.information(None, "提示", "输入地址或域名错误")
                return
            ip_address = socket.getaddrinfo(content, 80)
            content = ip_address[0][4][0]

        response = requests.get(f'http://apis.juhe.cn/ip/ipNewV3?key=e75b1e706ea6307f57c8f3fa93f0d136&ip={content}', timeout=500)
        res = response.json()['result']
        self.plainTextEdit_3.setPlainText(f"归属地：{res['Country']}{res['Province']}{res['City']} [{res['Isp']}]")


    def update_time(self, index):
        if index == 2:
            self.show_current_time()

    def show_current_time(self):
        time_format = dateTimeUtil.now_datetime()
        self.label_43.setText(time_format)
        threading.Timer(1.0, self.show_current_time).start()

    def time_transformation(self):
        val = self.lineEdit_13.text()
        if len(val) == 0:
            bit = self.button_group.checkedButton().text()[0:2]
            time_stamp = dateTimeUtil.now(int(bit))
            self.lineEdit_13.setText(str(time_stamp))
            if bit == '13':
                time_stamp = round(time_stamp / 1000)
        else:
            if len(val) != 10 and len(val) != 13:
                QMessageBox.critical(None, "提示", "格式错误")
                return
            elif len(val) == 13:
                time_stamp = round(int(val) / 1000)
            else:
                time_stamp = int(val)
        format_str = self.comboBox_4.currentText()
        self.lineEdit_14.setText(dateTimeUtil.date_format(format_str, int(time_stamp)))




if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWin = MyWindow()
    myWin.show()
    sys.exit(app.exec())
